package com.fxwater.api;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Map;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.util.ClassUtils;
import org.springframework.util.TypeUtils;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.PrettyPrinter;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fxwater.common.core.domain.AjaxResult;

/**
 * 自定义MessageConverter
 * 
 * @author tzh
 * @date 2018年5月18日 下午5:42:47
 */
public class LYJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {

    private static final boolean jackson26Available = ClassUtils.hasMethod(ObjectMapper.class,
            "setDefaultPrettyPrinter", PrettyPrinter.class);

    @SuppressWarnings("deprecation")
    @Override
    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {
        // 响应用户给的数据
        Object _obj = object;
        if (object instanceof AjaxResult) {
        } else if (object instanceof Map) {
            _obj = AjaxResult.success(object);
        }
        
        JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
        JsonGenerator generator =
                this.objectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding);
        try {
            writePrefix(generator, _obj);

            Class<?> serializationView = null;
            FilterProvider filters = null;
            Object value = _obj;
            JavaType javaType = null;
            if (_obj instanceof MappingJacksonValue) {
                MappingJacksonValue container = (MappingJacksonValue) _obj;
                value = container.getValue();
                serializationView = container.getSerializationView();
                filters = container.getFilters();
            }
            if (jackson26Available && type != null && value != null
                    && TypeUtils.isAssignable(type, value.getClass())) {
                javaType = getJavaType(type, null);
            }
            ObjectWriter objectWriter;
            if (serializationView != null) {
                objectWriter = this.objectMapper.writerWithView(serializationView);
            } else if (filters != null) {
                objectWriter = this.objectMapper.writer(filters);
            } else {
                objectWriter = this.objectMapper.writer();
            }
            if (javaType != null && javaType.isContainerType()) {
                objectWriter = objectWriter.withType(javaType);
            }
            objectWriter.writeValue(generator, value);

            writeSuffix(generator, _obj);
            generator.flush();
        } catch (JsonProcessingException ex) {
            throw new HttpMessageNotWritableException("Could not write content: " + ex.getMessage(),
                    ex);
        }
    }
}
